package top.java.commonClass;

import org.junit.Test;

/**
 *      String:字符串      用一对 "" 引起了表示
 *      1.String声明为final的，不可被继承的
 *      2.String实现了Comparable接口，表示String可以比较大小
 *            实现了Serializable接口，表示String是支持序列化的
 *      3.String内部定义了 final char value[] 用于存储字符串数据
 *
 *      4.String 代表不可变的字符序列   即：不可变性
 *          1.当对字符串重新赋值时，需要重写指定内存区域赋值，不能使用原有的value进行赋值
 *          2.当对现有的字符串进行连接操作时，也需要重新指定内存区域赋值，不能使用原有的value进行赋值
 *          3.当调用String中的replace()方法修改指定字符或者字符串时，也需要重新指定内存区域
 *      5.通过字面量的方式给一个字符串赋值，此时的字符串值声明在字符串常量池中
 *      6.字符串常量池中是不会存储相同内容的字符串的
 *
 *
 *
 */
public class StringTest1 {
    public static void main(String[] args) {

    }

    @Test
    public void test1() {
        String s1 = "abc";          //字面量的定义方式
        String s2 = "abc";

        System.out.println(s1 == s2);   //true

        s1 = "hello";
        System.out.println(s1);     //hello
        System.out.println(s2);     //abc

        System.out.println("*****************");
        String s3 = "abc";
        s3 += "def";
        System.out.println(s3);
        System.out.println(s2);

        System.out.println("*****************");
        String s4 = "abc";
        String s5 = s4.replace('a','v');
        System.out.println(s4);
        System.out.println(s5);
    }


    /**
     *  String的不同实例化对比
     */
    @Test
    public void test2() {

        String s1 = "abc";                //通过字面量定义的方式：字符串常量存储在字符串常量池，目的是共享
        String s2 = "abc";

        String s3 = new String("abc");   //通过new + 构造器的方式：字符串非常量对象，存储在堆中
        String s4 = new String("abc");

        System.out.println(s1 == s2);       //true
        System.out.println(s1 == s4);       //false
        System.out.println(s3 == s4);       //false

        System.out.println("*******************");
        Person t1 = new Person("Tom",12);
        Person t2 = new Person("Tom",12);
        System.out.println(t1.name == t2.name);     //true

        //在内存中创建了几个对象  (两个：一个是堆空间new结构，另一个是常量池中的char[])
        String s5 = new String("abc");
    }

    @Test
    public void test3() {
        String s1 = "ab";
        String s2 = "cc";

        String s3 = "abcc";
        String s4 = "ab" + "cc";
        String s5 = s1 + s2;
        String s6 = s1 + "cc";
        String s7 = "ab" + s2;

        System.out.println(s3 == s4);       //true
        System.out.println(s3 == s5);       //false
        System.out.println(s3 == s6);       //false
        System.out.println(s3 == s7);       //false

        System.out.println(s4 == s6);       //false
        System.out.println(s4 == s5);       //false

        s7 = s7.intern();
        System.out.println(s3 == s7);       //true

        final String s8 = "ab";
        String s9 = s8 + "cc";
        System.out.println(s9 == s3);       //true   常量与常量的拼接结果在常量池中,被final修饰的变量为常量

        /**
         *  结论：
         *      常量与常量的拼接结果在常量池中，且常量池中不会存在相同内容的常量
         *      只要其中有一个是变量，结果就在堆中
         *      如果拼接的结果调用intern()方法，返回值就在常量池中
         */
    }

}

class Person {
    String name;
    int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
